/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "UI.h"
#include "布局.h"

#include "intern/ui散列视口.h"
#include "intern/ui容器部件.h"
#include "intern/ui3D视口.h"
#include "intern/ui图像视频.h"
#include "intern/ui标量部件.h"
#include "intern/ui列表.h"
#include "intern/ui按钮.h"
#include "intern/事件处理.h"
#include "底层绘图/底层绘图框架.h"
#include "底层绘图/S_纹理.h"

#include "实例部件/ui文件对话框.h"
#include "实例部件/ui矢量数据部件.h"

#include "窗口/窗口.h"
#include "物体/S_摄像机.h"

#include "core/属性.h"
#include "core/时间.h"

#include "实例部件/ui菜单.h"

#include "ui绘制模板.h"
#include "ui绘制工具_组合部件.h"
#include "数学/数学.h"

#include "场景/场景.h"
#include "Input/Input.h"


#include <vulkan/vulkan.h>
#include <几何图形/图形相交.h>
#include <公共函数.h>
//#include <平面.h>
#include <time.h>


using namespace std;

//static uint8		g_焦点数量 = 0;
//static C_Widget*	g_焦点组件[128] = {};
static C_Widget*	g_上一轮焦点组件 = 0;


static float64 gdur;
static clock_t g时间start = clock();
static clock_t g时间end;
static float32 g双击时间 = 0;

static std::vector<S_纹理填充列队>				g_纹理填充列队;

static std::map<uint64, fp_Widget全局按键按下>	g_全局按键事件;
static std::vector<S_键盘键位映射>				g_全局键盘事件;
static std::vector<S_鼠标键位映射>				g_全局鼠标事件;
static uint8 g键盘按下数量 = 0;


//static uint8 g鼠标按下数量 = 0;
//static uint8 g键盘以按下键[4] = {};
//static C_Widget*	g上一次焦点组件[128] = {};
//static int16		g上一次焦点组件数量 = 0;



static void f_绘制子组件收集(C_Widget* root, C_Widget* self, S_UI渲染区域& 渲染区域组件, const uint32 层) {
	if (self->m_区域帧缓存根 && self->m_区域帧缓存根 != root) {
		return;
	}

	//self->m_更新下层绘制 = false;
	if (self->m_画布) {
		渲染区域组件.m_渲染组件.push_back(self);
	}

	for (auto& e : self->m_子组件) {
		f_绘制子组件收集(root, e, 渲染区域组件, 层);
	}
}




static void f_release子部件(C_Widget* w) {
	uint32 num = w->m_子组件.size();
	if (num) {
		auto* p = w->m_子组件.data();

		for (uint16 i = 0; i < num; ++i) {
			f_release子部件(p[i]);
			delete p[i];
			p[i] = nullptr;
		}

		w->m_子组件.clear();
	}
}



C_Widget管理* f_create组件管理(S_UI渲染环境& Ctx, uvec2 viewSize) {
	auto gm = new C_Widget管理(Ctx);
	gm->m_Root = 0;
	
	gm->视口.width = viewSize.x;
	gm->视口.height = viewSize.y;

	gm->m_模糊纹理大小 = (viewSize >> 2) / 16 * 16 + 16;

	Ctx.m_GM = gm;
	return gm;
}

void f_release组件管理(C_Widget管理* gm) {
	for (auto& w : gm->m_根部件切换组) {
		delete w;
	}
	gm->m_根部件切换组.clear();
	delete gm;
}

C_Widget* f_ui_创建组件(S_UI渲染环境* ctx) {
	return new C_Widget(ctx);
}

void f_ui_销毁组件(C_Widget* w) {
	delete w;
}

S_Props f_ui_getProp(C_Widget* w) {
	//return w->f_getProp();
	return {};
}







C_Widget* f_创建拖拽面板(const vec2& pos, const vec2& size) {
	C_Widget* w = new C_Widget();
	w->f_setPos(pos);
	w->f_setSize(size);

	return w;
}

C_Widget* f_创建填充布局(const vec2& pos, const vec2& size, const vec4& 边距){
	C_Widget* w = new C_Widget();
	w->mf_布局 = f_填充布局;
	return w;
}

C_Widget* f_创建分割布局(const vec2& pos, const vec2& size, E_方向 方向) {
	return nullptr;
}

C_Widget* f_创建框架布局(const vec2& pos, const vec2& size, const vec4& 边距) {
	C_Widget* w = new C_Widget();
	w->f_setPos(pos);
	w->f_setSize(size);

	return w;
}

void f_ui_替换子组件(C_Widget* self, int32 id, C_Widget* w) {
	self->f_替换子组件(id, w);
}

C_Widget* f_ui_创建根部件(const vec2& 位置比, const vec2& 大小比, E_布局方式 方式) {
	C_Widget* w = new C_Widget();
	w->m_TypeName = DEF_WIDGET_根布局;
	w->m_布局方式 = 方式;
	switch (方式) {
		case E_布局方式::e_填充布局:
			w->mf_布局 = f_填充布局;
			break;
		case E_布局方式::e_VBOX布局:
			w->mf_布局 = f_VBOX布局;
			break;
		case E_布局方式::e_网格:
			w->mf_布局 = f_Layout_网格;
			break;
		default:
			break;
	}

	f_widget_set绘制根区域组件(w, w);
	return w;
}

C_Widget* f_ui_创建分割框(const std::vector<C_Widget*>& ws, E_方向 dir, const std::vector<float32>& 分割比, S_UI渲染环境& ctx) {
	auto* w = new C_分割框(ctx, dir);

	uint32 分割数量 = ws.size();

	float32 比例 = 1.0 / (分割数量);
	for (uint32 i = 0; i < 分割数量; ++i) {
		w->f_add分割(ws[i], 分割比[i]);
	}
	
	return w;
}

E_方向 f_ui_get分割框排列方向(C_Widget* self) {
	return static_cast<C_分割框*>(self)->m_排列方向;
}

std::vector<float32> f_ui_get分割框分割比例(C_Widget* self) {
	return static_cast<C_分割框*>(self)->m_分割比例;
}

C_Widget* f_散列视口(const vec2& pos, const vec2& size, S_UI渲染环境& ctx) {
	C_Widget* w = new C_散列视口(ctx);
	w->f_setPos(pos);
	w->f_setSize(size);

	w->mf_布局 = f_散列布局;
	return w;
}


C_Widget* f_ui_创建图像视口(S_UI渲染环境& ctx, uint8 缓存数量) {
	auto 视频框 = new C_视频框(ctx, 缓存数量);
	return 视频框;
}


C_Widget* f_ui_创建bool值编辑框(S_UI渲染环境& ctx, fp_Widget布尔值回调 func) {
	auto* w = new C_编辑框Bool(ctx);
	w->mf_值改变回调 = func;
	return w;
}


C_Widget* f_ui_创建vec编辑框(S_UI渲染环境& ctx) {
	C_Vec* w = new C_Vec(E_方向::e_纵向, ctx);
	auto e = (C_文本框**)(w->m_子组件.data());
	return w;
}

C_Widget* f_ui_创建编辑框(S_UI渲染环境& ctx, fp_Widget文本回调 f文本输入, fp_Widget文本输入完成 f输入完成, std::u16string 字体名称) {
	C_文本编辑框* edit = new C_文本编辑框(ctx, 字体名称);
	C_滚动框* box = new C_滚动框(ctx, true, true, edit);
	edit->mf_文本输入 = f文本输入;
	edit->mf_文本完成 = f输入完成;
	return box;
}

C_Widget* f_ui_创建可编辑文本下拉框(S_UI渲染环境& ctx) {
	C_下拉列表框* list = new C_下拉列表框(ctx);
	return list;
}


std::u16string f_ui_取行编辑框文本(C_Widget* self) {
	return static_cast<C_文本框*>(self)->m_Text;
}

C_Widget* f_ui_创建颜色选框(S_UI渲染环境& ctx, S_Props& prop) {
	return new C_RGBA8选择框(ctx, prop);
}



static bool on_文件对话框打开关闭(C_Widget* self, bool show) {
	C_文件对话框* 对话框 = dynamic_cast<C_文件对话框*>(self);
	f_ui_对话框填充系统目录(对话框);
	return true;
}

C_Widget* f_ui_创建文件对话框(S_UI渲染环境& ctx, std::string 初始路径) {
	auto* filedialog = new C_文件对话框(ctx);
	filedialog->mf_打开关闭 = on_文件对话框打开关闭;
	return filedialog;
}

void f_ui_设置文件对话框类型(C_Widget* fw, E_对话框类型 type) {
	C_文件对话框* filedialog = dynamic_cast<C_文件对话框*>(fw);

	if (filedialog) {
		//filedialog->m_文件处理方式 = type;
		filedialog->f_set对话框模式(type);
	}
}




C_Widget* f_ui_get滚动框视口(C_Widget* self) {
	C_滚动框* sbox = dynamic_cast<C_滚动框*>(self);
	assert(sbox);
	if(sbox) return sbox->m_View;
	return nullptr;
}

std::u16string f_ui_get编辑框文本(C_Widget* self) {
	C_文本框* box = dynamic_cast<C_文本框*>(self);
	return box->m_Text;
}

C_文本框* f_ui_from滚动框取文本视口(C_Widget* self) {
	C_滚动框* sbox = dynamic_cast<C_滚动框*>(self);
	if (sbox) return dynamic_cast<C_文本框*>(sbox->m_View);
	return nullptr;
}




void f_ui_打开对话框(S_Window* w, E_对话框类型 type, fp_文件处理回调 fun, std::string path, std::u16string 后缀, bool 内嵌窗口) {
	S_Window* window = (S_Window*)(w);
	C_Widget管理* gm = f_window_getUI管理(window);
	C_Widget* dig = gm->m_Root;

	f_ui_打开对话框(gm, dig, type, fun, path, 后缀, 内嵌窗口);

	f_window_set显示(window, true);
}

void f_ui_打开对话框(C_Widget管理* gm, C_Widget* w, E_对话框类型 type, fp_文件处理回调 fun, std::string path, std::u16string 后缀, bool 内嵌窗口) {
	
	C_文件对话框* dig = dynamic_cast<C_文件对话框*>(w);
	if (dig) {
		dig->m_路径 = path;
		dig->m_过滤后缀 = { 后缀 };
		dig->mf_文件处理回调 = fun;

		dig->f_set对话框模式(type);

		f_文件对话框打开关闭(dig, true);
	}
	
	if (内嵌窗口) {
		f_widget_top_push(gm, dig);
	}
}

void f_ui_关闭对话框(C_Widget管理* gm, C_Widget* w, uint16 id) {
	f_ui_switchRootWidget(gm, id);
}



void f_ui_打开弹出窗口(C_Widget* self, vec2 pos, C_Widget* 发起组件, bool 延迟构建) {
	f_widget_加入顶层绘图(self);
	
	switch (self->m_Type) {
		case E_WidgetType::t_菜单: {
			C_菜单* menu = dynamic_cast<C_菜单*>(self);

			if (menu) {
				if (延迟构建) {
					//S_菜单延迟构建缓存 构建缓存;
					//构建缓存.m_菜单构建参数;
				}
				else {
					if (menu->mui_搜索框) {
						menu->mui_搜索框->m_Text = u"";
					}
					menu->mui_发起组件 = 发起组件;

					menu->m_窗口层 = f_widget_top_push(menu, menu->m_窗口层-1);

					pos = f_菜单坐标矫正(menu, pos);
					menu->f_打开(pos);
				}
			}
			break;
		}
		case E_WidgetType::t_弹出消息框: {
			C_弹出信息框* box = dynamic_cast<C_弹出信息框*>(self);
			box->m_窗口层 = f_widget_top_push(box, f_widget_getTopNum(self->f_get窗口管理()));
			box->f_setPos(pos);
			box->m_GlobalLoc = pos;
			break;
		}
		default: {
			self->m_窗口层 = f_widget_top_push(self, f_widget_getTopNum(self->f_get窗口管理()));
			self->f_setPos(pos);
			self->m_GlobalLoc = pos;
			break;
		}
	}
}

void f_ui_关闭弹出窗口(C_Widget* self) {
	
	switch (self->m_Type) {
		case E_WidgetType::t_菜单: {
			f_菜单_关闭(static_cast<C_菜单*>(self));
			break;
		}
		case E_WidgetType::t_弹出消息框: {
			break;
		}
		default: {
			auto gm = self->f_get窗口管理();
			f_widget_顶层窗口_pop(gm, self->m_窗口层 - 1);
			self->m_窗口层 = 0;
		}
	}

}



uint32 f_ui_多页面添加页面(C_Widget* w, C_Widget* page, int8 loc) {
	C_多页面* mpage = dynamic_cast<C_多页面*>(w);
	mpage->f_add页面(page, loc);
	return mpage->m_分页面.size();
}

void f_ui_设置多页面头(C_Widget* w, vec2 size) {
	auto* page = dynamic_cast<C_多页面*>(w);
	page->m_头大小 = size;
}

void f_ui_设置多页面标签文本(C_Widget* w, uint16 id, const std::u16string& text) {
	auto* page = dynamic_cast<C_多页面*>(w);
	if (page) {
		++id;
		if (id < page->m_子组件.size()) {
			page->m_子组件[id]->m_WName = text;
		}
	}
}

void f_ui_set图像视口纹理(C_Widget* w, S_纹理* tex, uint32 frameOffset) {
	auto* view = dynamic_cast<C_视频框*>(w);
	if (view) {
		view->f_set槽纹理(tex, 0);
		//f_vg_set纹理(view->m_笔刷, 0, tex);
	}
}

void f_ui_图像视口填充捕捉点(C_Widget* w, std::vector<S_Rect2Df>& 点坐标, std::vector<S_RGBA8UI>& 点颜色) {
	auto* view = dynamic_cast<C_视频框*>(w);
	if (view) {
		f_视频框_填充视频捕捉点(view, 点坐标, 点颜色);
	}
}

void f_ui_图像视口_设置选区(C_Widget* w, const S_Rect2Df& 点坐标, const S_RGBA8UI& 点颜色) {
	auto* view = dynamic_cast<C_视频框*>(w);
	if (view) {
		f_视频框_设置选取(view, 点坐标, 点颜色);
	}
}

void f_ui_图像视口_关闭选区(C_Widget* w) {
	auto* view = dynamic_cast<C_视频框*>(w);
	if (view) {
		f_视频框_关闭选取(view);
	}
}

void f_ui_设置bool值编辑框引用值(C_Widget* w, S_Props prop) {
	auto* view = dynamic_cast<C_编辑框Bool*>(w);
	if (view) {
		view->m_自定义属性 = prop;
		view->m_自定义属性.m_UI->m_部件 = view;
		//view->m_Value.m_部件 = view;
		view->f_刷新();
	}
}

//void f_ui_文本框插入行文本(C_Widget* w, std::u16string text, int32 行) {
//	C_文本编辑框* box = dynamic_cast<C_文本编辑框*>(w);
//
//	S_文档文本 块;
//	块.m_Text = text;
//	box->m_文档->m_字文本块.push_back(块);
//}

bool f_ui_编辑框开关编辑(C_Widget* self, bool open)  {
	return false;
}

void f_ui_set数值部件布尔值(C_Widget* self) {
	C_编辑框Bool* box = dynamic_cast<C_编辑框Bool*>(self);
	if (box) {
		(*((bool*)box->m_自定义属性.m_Value)) = !(*((bool*)box->m_自定义属性.m_Value));
	}
}

bool f_ui_文本部件完成输入(C_Widget* self) {
	//if (C_文本框::g当前操作文本框 && C_文本框::g当前操作文本框 != self) {
	//	C_文本框::g当前操作文本框->f_输入完成();
	//}
	return false;
}

void f_ui_set文本框框选回调(C_Widget* self, fp_Widget更新 选时, fp_Widget更新 选后) {
	C_文本框* box = dynamic_cast<C_文本框*>(self);
	if (box) {
		box->mf_框选时回调 = 选时;
		box->mf_框选后回调 = 选后;
	}
}

vec2 f_ui_行编辑框光标位置(C_Widget* self) {
	C_文本框* box = dynamic_cast<C_文本框*>(self);
	return box->g光标绘制位置;
}

bool f_ui_文本部件全选(C_Widget* self, uvec2 range) {
	C_文本框* box = dynamic_cast<C_文本框*>(self);
	//box->m_行选框左边和右边.x;
	return false;
}

//void f_ui_set文本编辑框文本(C_Widget* self, S_文档文本& txt) {
//	auto box = dynamic_cast<C_文本编辑框*>(self);
//	box->m_光标坐标索引 = {};
//	box->m_选取 = {};
//	box->m_文档->m_文本块 = txt.m_文本块;
//	box->m_文档->m_Color = txt.m_Color;
//}

void f_ui_setVec布局方向(C_Widget* self, E_方向 方向) {
	assert(dynamic_cast<C_Vec*>(self));
	((C_Vec*)self)->f_切换布局方向(方向);
	self->m_更新绘制属性 = true;
}

void f_ui_3dView_渲染(C_Widget* self) {
	assert(dynamic_cast<C_3D视口*>(self));
	static_cast<C_3D视口*>(self)->f_渲染();
	//std::cout << "三维渲染" << std::endl;
}

S_Rect2Df f_ui_get视口(C_Widget* self) {
	return { {0,0}, {self->m_Size.x, self->m_Size.y} };
}

void f_ui_3dView_set部件帧绘制(C_Widget* self, bool 暂停) {
	C_3D视口* view = dynamic_cast<C_3D视口*>(self);
	if (view) {
		if (暂停) {
			view->m_锁.lock();
		} else {
			view->m_锁.unlock();
		}
	}
}

S_文档文本* f_ui_get文档数据(C_Widget* self) {
	C_滚动框* box = dynamic_cast<C_滚动框*>(self);
	if (box) {
		C_文本编辑框* v = dynamic_cast<C_文本编辑框*>(box->m_View);
		if (v) {
			return v->m_文档;
		}
	}
	return nullptr;
}

//uint32 f_ui_get文档文本总字符数(const S_文档文本& doc) {
//	uint32 num = 0;
//	uint32 行数量 = doc.m_文本块.size();
//	for (uint32 y = 0; y < 行数量; ++y) {
//		num += doc.m_文本块[y].size();
//	}
//	return num;
//}

bool f_ui_路径编辑框打开对话框(C_Widget* self, C_Widget管理* gm) {
	assert(dynamic_cast<C_路径编辑器*>(self));
	C_路径编辑器* box = (C_路径编辑器*)self;

	f_ui_switchRootWidget(gm, box->mui_对话框->m_实例ID);
	
	return true;
}

bool f_ui_路径编辑框是否打开(C_Widget* self) {
	C_路径编辑器* box = (C_路径编辑器*)self;
	return box->m_对话框是否打开;
}

void f_ui_bind文本编辑框文档(C_Widget* self, S_文档文本* doc) {
	auto* box = dynamic_cast<C_文本框*>(self);
	if (box) {
		box->m_文档 = doc;
		box->m_光标坐标索引 = {0,0};
		box->m_选取 = { {},{} };
	}
}




C_Widget* f_ui_PropWidget(S_UI渲染环境& ctx, S_Props& prop, E_方向 布局, C_Widget* 附加组件) {
	C_Widget* w = nullptr;

	E_方向 方向 = E_方向::e_横向;
	switch (prop.m_布局方式) {
		case E_布局方式::e_VBOX布局: {
			方向 = E_方向::e_纵向;
			break;
		}
		case E_布局方式::e_HBOX布局: {
			方向 = E_方向::e_横向;
			break;
		}
		default:
			break;
	}

	switch (prop.m_Type) {
		case E_值类型::e_Type_None: {
			w = new C_Widget();
			w->m_是否延展 = { true, true };
			break;
		}

		case E_值类型::e_Type_Str: {
			w = f_ui_创建标签(ctx);
			break;
		}

		case E_值类型::e_Type_LineText: {
			w = f_ui_创建行文本编辑框(ctx);
			break;
		}

		case E_值类型::e_Type_路径: {
			w = f_ui_创建路径编辑框(ctx, 附加组件, nullptr);
			break;
		}

		case E_值类型::e_Type_Operator: {
			w = f_ui_创建按钮(&ctx);
			break;
		}

		case E_值类型::e_Type_UI32位域枚举:
		case E_值类型::e_Type_UI32Ops:
		case E_值类型::e_Type_Enum: {
			w = f_ui_创建枚举选择框(ctx, 方向);
			w->f_bind属性(prop);
			f_ui_bind枚举部件属性(w, prop);
			break;
		}

		case E_值类型::e_Type_Bool:
			w = f_ui_创建bool值编辑框(ctx);
			f_ui_设置bool值编辑框引用值(w, prop);
			break;

		case E_值类型::e_Type_I8:
		case E_值类型::e_Type_UI8:
		case E_值类型::e_Type_I32:
		case E_值类型::e_Type_UI32:
		case E_值类型::e_Type_F32:
		case E_值类型::e_Type_UI64:
			w = f_ui_创建数值编辑框(ctx);
			w->f_setSize({80, 24});
			break;

		case E_值类型::e_Type_iVec2:
		case E_值类型::e_Type_Vec2:
		case E_值类型::e_Type_uVec2:
			w = f_ui_创建vec编辑框(ctx);
			w->f_setSize({ 80, 24 * 2 });
			f_ui_setVec布局方向(w, 方向);
			break;


		case E_值类型::e_Type_iVec3:
		case E_值类型::e_Type_uVec3:
		case E_值类型::e_Type_Vec3:
		case E_值类型::e_Type_Vec4:
			w = f_ui_创建vec编辑框(ctx);
			w->f_setSize({ 80, 24 * 3 });
			break;


		case E_值类型::e_Type_UI32_FlagBits:
		case E_值类型::e_Type_Bool_1D: {
			w = f_ui_创建多选框(ctx);
			break;
		}

		case E_值类型::e_Type_MapPtr_Array1D: {
			w = f_ui_创建下拉列表(ctx, true);
			f_ui_绑定下拉列表属性(w, prop);
			break;
		}
		case E_值类型::e_Type_映射引用_2D: {
			w = f_ui_创建超级列表编辑框(ctx, true);
			break;
		}

		case E_值类型::e_Type_RGB:
		case E_值类型::e_Type_RGBA:
		case E_值类型::e_Type_纹理:
			w = f_ui_创建拾色器(ctx, prop);
			f_ui_拾色器绑定属性(w, prop);
			break;

		case E_值类型::e_Type_TexProp:
			w = f_ui_创建过程纹理图像框(ctx);
			f_ui_bind图像框纹理属性(w, prop);
			break;

		case E_值类型::e_Type_2D曲线: {
			w = f_ui_创建曲线采样器(ctx);
			f_ui_曲线采样器绑定属性数据(w, prop);
			break;
		}

		case E_值类型::e_Type_Node: {
			break;
		}
		case e_Type_UI8位域枚举: {
			w = f_ui_创建多选框(ctx);
			f_ui_bind多选框属性(w, prop, 布局);
			break;
		}

		case E_值类型::e_Type_Object_1D:
		case E_值类型::e_Type_SocketContainer:
			//if (m_插座列表框_部件.size() > m_插座列表框使用计数) {
			//	w = m_插座列表框_部件[m_插座列表框使用计数];
			//}
			//else {
			//	
			//	m_插座列表框_部件.emplace_back(w);
			//}
			//w = new C_编辑列表(ctx);
			//f_插座编辑列表绑定属性数据(w, e, E_编辑列表类型::e_插座列表);
			//++m_插座列表框使用计数;
			break;

		case E_值类型::e_Type_PropContainer:
		case E_值类型::e_Type_ContainerBool:
		case E_值类型::e_Type_ContainerF32:
		case E_值类型::e_Type_ContainerI8:
		case E_值类型::e_Type_ContainerI32:
		case E_值类型::e_Type_ContainerUI32:
		case E_值类型::e_Type_ContainerVec2:
		case E_值类型::e_Type_ContainerVec3:
		case E_值类型::e_Type_ContainerVec4:
		case E_值类型::e_Type_ContaineriVec2:
		case E_值类型::e_Type_ContaineriVec3:
		case E_值类型::e_Type_ContaineriVec4:
		case E_值类型::e_Type_ContainerBound:
		case E_值类型::e_Type_ContainerValue: {
			//if (m_插座列表框_部件.size() > m_插座列表框使用计数) {
			//	w = m_插座列表框_部件[m_插座列表框使用计数];
			//}
			//else {
			//	w = f_创建插座编辑列表(*m_UIctx);
			//	m_插座列表框_部件.emplace_back(w);
			//}
			//e.m_UI->m_部件 = w;
			//f_插座编辑列表绑定属性数据(w, e, E_编辑列表类型::e_F32列表);
			//++m_插座列表框使用计数;
			break;
		}

		case E_值类型::e_Type_LayoutList: {
			//if (m_分组框.size() > m_分组框使用计数) {
			//	w = m_分组框[m_分组框使用计数];
			//}
			//else {
			//	w = new C_Widget;
			//	m_分组框.push_back(w);
			//}
			//
			//w->m_实例ID = m_分组框使用计数;
			//++m_分组框使用计数;
			//
			//w->m_TypeName = f_WStringToString(e.m_Name);
			//e.m_UI->m_部件 = w;
			//++i;
			//f_添加子组件(w);
			//
			//auto& container = f_prop_Container(e);
			//f_重新构建组件(container.m_Item);
			//continue;
		}
		default: w = nullptr; return nullptr;
	}

	w->f_bind属性(prop);
	w->m_TypeName = f_str_u16_to_u8(prop.m_Name);
	w->m_自定义属性 = prop;
	prop.m_UI->m_部件 = w;
	return w;
}

std::vector<C_Widget*> f_ui_从属性构建组件(C_Widget* self, std::vector<S_Props>& 属性,  E_布局方式 布局方式) {
	std::vector<C_Widget*> 组件集;
	for (auto& e : 属性) {
		组件集.push_back(f_ui_PropWidget(*self->m_UIctx, e, E_方向::e_横向));
	}
	return 组件集;
}







void f_部件设置布局(C_Widget* w, E_布局方式 方式) {
	switch (方式) {
		case E_布局方式::e_HBOX布局:
			break;
		case E_布局方式::e_VBOX布局:
			break;
		case E_布局方式::e_填充布局: {
				S_比例布局* l = new S_比例布局();
				l->m_位置比例 = { 0.0f,0.0f };
				l->m_大小比例 = { 1.0f,1.0f };
				//w->m_布局器 = l;
			}
			break;
		case E_布局方式::e_BOX布局:
			break;
		default:
			break;
	}
}


static void f_子组件裁剪(C_Widget* w) {
	if (w->mf_布局)w->mf_布局(w, w->m_子组件.data(), w->m_子组件.size());
	w->f_裁剪();

	if (w->m_被裁剪) return;

	uint32 num = w->m_子组件.size();
	if (!num) return;

	auto* p = w->m_子组件.data();
	for (uint32 i = 0; i < num; ++i) {
		f_子组件裁剪(p[i]);
	}
}

void f_ui_组件布局(C_Widget管理* gm, const vec4& area) {
	/****************************************************************
	*           调整和裁剪顶层窗口
	*****************************************************************/
	auto topWidget = f_widget_getTop(gm);
	for (uint8 i = 0; i < topWidget.m_Num; ++i) {
		topWidget.m_W[i]->f_setSize({ area.z, area.w });
		f_子组件裁剪(topWidget.m_W[i]);
	}


	/****************************************************************
	*           调整和裁剪常规窗口
	*****************************************************************/
	uint32 num = gm->m_根部件切换组.size();
	for (uint8 i = 0; i < num; ++i) {
		gm->m_根部件切换组[i]->f_setSize({ area.z, area.w });
		f_子组件裁剪(gm->m_根部件切换组[i]);
	}
}




/*static bool f_筛选焦点组件(C_Widget* w, const vec2& point) {
	uint32 num = w->m_子组件.size();
	if (!num) return 0;
	auto p = w->m_子组件.data();


	C_Widget* tem[8];
	for (uint32 depth = 1; ; ++depth) {
		bool 无焦点组件 = true;

		uint32 未被裁剪数量 = 0;
		//for (uint32 i = 0; i < num; ) {
		for (int32 i = num-1; i >= 0; ) {
			//std::cout << "A== " << depth << " == " << int(i) << p[i]->m_Name << std::endl;
			if (!(p[i]->m_被裁剪)) {
				tem[未被裁剪数量] = p[i];
				++未被裁剪数量;
			}

			--i;
			//从8个组件中筛选在坐标点的组件
			if (未被裁剪数量 >= 8 || i < 0) {
				auto id = f_widget_筛选焦点组件_avx(tem, 未被裁剪数量, point);

				未被裁剪数量 = 0;
				if (id >= 0 && tem[id]->m_拾取) {
					
					//g_焦点组件[depth] = tem[id];
					g_焦点组件[C_Widget::g_焦点数量] = tem[id];
					++C_Widget::g_焦点数量;


					//子部件绑定到当前层部件指针
					num = tem[id]->m_子组件.size();
					p = tem[id]->m_子组件.data();

					//std::cout << "A== " << depth << " == " << int(i) << tem[id]->m_Name << 无焦点组件 << std::endl;
					无焦点组件 = false;
					break;
				}
			}
		}

		if (无焦点组件) break;
	}
	
	return C_Widget::g_焦点数量;
}*/

void f_ui_筛选焦点组件(C_Widget管理* gm, const vec2& point) {
	/****************************************************************
	*                   筛选顶层焦点窗口
	*****************************************************************/
	
	C_Widget* 焦点组件[128]{};

	auto 筛选组件 = [&](C_Widget* w, const vec2& point, int8& 拾取计数) -> int32 {
		uint32 num = w->m_子组件.size();
		if (!num) return 0;
		auto p = w->m_子组件.data();


		C_Widget* tem[8];
		for (uint32 depth = 1; ; ++depth) {
			bool 无焦点组件 = true;

			uint32 未被裁剪数量 = 0;
			for (int32 i = num-1; i >= 0; ) {
				//std::cout << "A== " << depth << " == " << int(i) << p[i]->m_Name << std::endl;
				if (!(p[i]->m_被裁剪)) {
					tem[未被裁剪数量] = p[i];
					++未被裁剪数量;
				}

				--i;
				//从8个组件中筛选在坐标点的组件
				if (未被裁剪数量 >= 8 || i < 0) {
					auto id = f_widget_筛选焦点组件_avx(tem, 未被裁剪数量, point);

					未被裁剪数量 = 0;
					if (id >= 0 && tem[id]->m_拾取) {
						焦点组件[拾取计数] = tem[id];
						++拾取计数;

						//子部件绑定到当前层部件指针
						num = tem[id]->m_子组件.size();
						p = tem[id]->m_子组件.data();

						//std::cout << "A== " << depth << " == " << int(i) << tem[id]->m_Name << 无焦点组件 << std::endl;
						无焦点组件 = false;
						break;
					}
				}
			}

			if (无焦点组件) break;
		}

		return 拾取计数;
	};



	auto topWidget = f_widget_getTop(gm);
	for (uint32 i = 0; i < topWidget.m_Num; ++i) {
		if (f_widget_点是否在组件内(topWidget.m_W[i], point) || topWidget.m_W[i]->m_强制焦点) {
			gm->m_弹出层组件拾取计数 = 0;
			焦点组件[0] = topWidget.m_W[i];
			
			gm->m_弹出层组件拾取计数 = 1;

			
			if (筛选组件(焦点组件[0], point, gm->m_弹出层组件拾取计数) > 1) {
				memcpy(&gm->m_焦点组件[gm->m_下层组件拾取计数], 焦点组件, sizeof(C_Widget*) * gm->m_弹出层组件拾取计数);
				gm->m_焦点数量 = gm->m_下层组件拾取计数 + gm->m_弹出层组件拾取计数;
			}
			else {
				//if (topWidget.m_W[i]->m_强制焦点) {
					gm->m_焦点组件[gm->m_下层组件拾取计数] = topWidget.m_W[i];
					gm->m_焦点数量 = gm->m_下层组件拾取计数 + gm->m_弹出层组件拾取计数;
				//}
			}
			return;
		}
	}
	
	gm->m_焦点数量 = 0;

	焦点组件[0] = gm->m_Root;
	gm->m_下层组件拾取计数 = 1;
	筛选组件(gm->m_Root, point, gm->m_下层组件拾取计数);

	memcpy(gm->m_焦点组件, 焦点组件, sizeof(C_Widget*) * gm->m_下层组件拾取计数);
	gm->m_焦点数量 = gm->m_下层组件拾取计数;
}





static bool f_执行全局键盘事件(const S_输入环境& input) {
	uint32 num = g_全局键盘事件.size();
	auto* keys = g_全局键盘事件.data();

	//memset(g键盘以按下键, 0, sizeof(uint8) * 4);
	//static uint32 记录 = 0;
	bool 跳过局部事件 = false;
	
	for (uint8 i = 0; i < num; ++i) {
		uint8 bit = 0;
		auto& key = keys[i];


		for (uint8 k = 0; k < 4; ++k) {
			if (key.键盘按键[k]) {
				bit |= 1 << k;
				if (f_键盘单个按键状态(input.m_Key.Keys状态, key.键盘按键[k], key.键盘状态[k])) {
					key.记录 |= 1 << k;
				}
			}
		}


		bool 控制键全部释放 = true;
		for (uint8 k = 0; k < 4; ++k) {
			if (input.m_Key.Keys状态[key.键盘按键[k]] != DEF_按键状态_准备) {
				控制键全部释放 = false;
			}
		}

		if (bit && key.记录 == bit) {
			key.event(nullptr, E_键位执行状态::e_开始);
			key.记录 = 0;
			跳过局部事件 = true;
			break;
		}

		if (控制键全部释放) {
			key.记录 = 0;
		}
	}

	if (跳过局部事件) {
		for (uint8 i = 0; i < num; ++i) {
			keys[i].记录 = 0;
		}
	}

	return 跳过局部事件;
}



void f_ui_执行输入设备事件(C_Widget管理* gm, const S_输入环境& input) {
	
	if (!gm->m_焦点数量) return;
	//f_widget_set当前窗口矩形(gm->窗口区域);

	gm->鼠标左键按下传递 = true;
	gm->鼠标左键放开传递 = true;
	gm->鼠标右键按下传递 = true;
	gm->鼠标右键放开传递 = true;
	gm->鼠标中键按下传递 = true;
	gm->鼠标中键放开传递 = true;
	
	gm->是否执行UI部件事件 = true;

	uint32 鼠标按键事件传递 = E_事件是否传递::e_事件传递_继续;


	gm->mf_输入执行前回调();

	

	ivec4 Mouse = { input.m_鼠标全局坐标.x, input.m_鼠标全局坐标.y, ((S_鼠标属性*)input.m_鼠标)->lX, ((S_鼠标属性*)input.m_鼠标)->lY };
	//static S_鼠标 鼠标;
	C_Widget::g_鼠标.lZ = ((S_鼠标属性*)input.m_鼠标)->lZ / 120;
	C_Widget::g_鼠标.gPos = { float32(input.m_鼠标全局坐标.x), float32(input.m_鼠标全局坐标.y) };
	C_Widget::g_鼠标.lPos = { float32(((S_鼠标属性*)input.m_鼠标)->lX), float32(((S_鼠标属性*)input.m_鼠标)->lY) };
	C_Widget::g_鼠标.abs = C_Widget::g_鼠标.gPos - C_Widget::g_鼠标.abs;
	//C_Widget::g_鼠标.相对窗口偏移.x = gm->窗口区域.x;
	//C_Widget::g_鼠标.相对窗口偏移.y = gm->窗口区域.y;
	C_Widget::g_键盘 = input.m_Key;
	
	//std::cout<<"C_Widget::g_鼠标.abs = "<< C_Widget::g_鼠标.abs.x << " : " << C_Widget::g_鼠标.gPos.x << std::endl;
	//std::cout << "C_Widget::g_鼠标 = " << ((S_鼠标属性*)input.m_鼠标)->lX << " : " << ((S_鼠标属性*)input.m_鼠标)->lY << std::endl;
	//if ((((S_鼠标属性*)input.m_鼠标)->lX > 1 || ((S_鼠标属性*)input.m_鼠标)->lY > 1) || (((S_鼠标属性*)input.m_鼠标)->lX < -1 || ((S_鼠标属性*)input.m_鼠标)->lY < -1)) {
	uint32 全局鼠标事件数量 = g_全局鼠标事件.size();


	E_事件是否传递 事件是否传递 = E_事件是否传递::e_事件传递_继续;
	bool 鼠标移动了 = false;
	static int32 鼠标移动距离 = 0;
	if (((S_鼠标属性*)input.m_鼠标)->lX || ((S_鼠标属性*)input.m_鼠标)->lY) {
		鼠标移动了 = true;
		//鼠标移动距离 += vec_len(vec2{float32(((S_鼠标属性*)input.m_鼠标)->lX), float32(((S_鼠标属性*)input.m_鼠标)->lY)}) - 鼠标移动距离;
		//gm->有输入事件 = true;
	}

	//std::cout<<"((S_鼠标属性*)input.m_鼠标)->rgbButtons[0] = "<< int32(((S_鼠标属性*)input.m_鼠标)->rgbButtons[0]) << std::endl;

	{
		if (((S_鼠标属性*)input.m_鼠标)->rgbButtons[0] ) {
			if(gm->鼠标按键状态[E_Input_鼠标按键::e_左键] == DEF_按键状态_准备) gm->鼠标按键状态[E_Input_鼠标按键::e_左键] = DEF_按键状态_按下;
		}
		else if(gm->鼠标按键状态[E_Input_鼠标按键::e_左键] == DEF_按键状态_按下中) {
			gm->鼠标按键状态[E_Input_鼠标按键::e_左键] = DEF_按键状态_放开;
		}

		if (((S_鼠标属性*)input.m_鼠标)->rgbButtons[1]) {
			if(gm->鼠标按键状态[E_Input_鼠标按键::e_右键] == DEF_按键状态_准备) gm->鼠标按键状态[E_Input_鼠标按键::e_右键] = DEF_按键状态_按下;
		}
		else if (gm->鼠标按键状态[E_Input_鼠标按键::e_右键] == DEF_按键状态_按下中) {
			gm->鼠标按键状态[E_Input_鼠标按键::e_右键] = DEF_按键状态_放开;
		}

		if (((S_鼠标属性*)input.m_鼠标)->rgbButtons[2]) {
			if (gm->鼠标按键状态[E_Input_鼠标按键::e_中键] == DEF_按键状态_准备) gm->鼠标按键状态[E_Input_鼠标按键::e_中键] = DEF_按键状态_按下;
		}
		else if (gm->鼠标按键状态[E_Input_鼠标按键::e_中键] == DEF_按键状态_按下中) {
			gm->鼠标按键状态[E_Input_鼠标按键::e_中键] = DEF_按键状态_放开;
		}

		//std::cout << "((S_鼠标属性*)input.m_鼠标)->lZ = " << ((S_鼠标属性*)input.m_鼠标)->lZ << std::endl;
		if (((S_鼠标属性*)input.m_鼠标)->lZ) {
			if (gm->鼠标按键状态[E_Input_鼠标按键::e_滚轮] == DEF_按键状态_准备) gm->鼠标按键状态[E_Input_鼠标按键::e_滚轮] = DEF_按键状态_按下;
		}
		else if (gm->鼠标按键状态[E_Input_鼠标按键::e_滚轮] == DEF_按键状态_按下中) {
			gm->鼠标按键状态[E_Input_鼠标按键::e_滚轮] = DEF_按键状态_放开;
		}
		C_Widget::g_鼠标.rgbButtons[E_鼠标按钮::e_鼠标左键] = gm->鼠标按键状态[E_鼠标按钮::e_鼠标左键];
		C_Widget::g_鼠标.rgbButtons[E_鼠标按钮::e_鼠标中键] = gm->鼠标按键状态[E_鼠标按钮::e_鼠标中键];
		C_Widget::g_鼠标.rgbButtons[E_鼠标按钮::e_鼠标右键] = gm->鼠标按键状态[E_鼠标按钮::e_鼠标右键];


		//cout << "input.m_Key.Keys[k] == " << int32(input.m_Key.Keys[56]) << endl;
		//static int32 old_a = 0;
		g键盘按下数量 = 0;
		for (uint16 k = 0; k < 256; ++k) {
			if (input.m_Key.Keys[k]) {
				if (input.m_Key.Keys状态[k] == DEF_按键状态_准备) input.m_Key.Keys状态[k] = DEF_按键状态_按下;
				++g键盘按下数量;

				gm->有输入事件 = true;
			}
			else {
				if (input.m_Key.Keys状态[k] != DEF_按键状态_准备) input.m_Key.Keys状态[k] = DEF_按键状态_放开;
			}
		}

		for (uint16 k = 0; k < 4; ++k) {
			if ( ((S_鼠标属性*)input.m_鼠标)->rgbButtons[k] ) {
				gm->有输入事件 = true;
			}
		}
	}

	int8 当前组件迭代ID = gm->m_焦点数量;




	/************************************** 拖拽事件 *********************************/
	if (gm->m_当前拖拽部件 && 鼠标移动了) {
		if (gm->执行鼠标点击) {
			gm->执行鼠标点击 = false;
		}

		if (gm->拖放状态 == DEF_拖放状态_开始拖放 && gm->m_当前拖拽部件->mf_开始拖拽) {
			gm->m_拖放数据 = {};
			gm->m_当前拖拽部件->mf_开始拖拽(gm->m_当前拖拽部件, C_Widget::g_鼠标, gm->m_拖放数据);
			gm->拖放状态 = DEF_拖放状态_拖放;
			gm->m_当前拖拽部件->m_拖放阻止鼠标进出事件 = true;
		}

		if (gm->拖放状态 == DEF_拖放状态_拖放) {
			事件是否传递 = gm->m_当前拖拽部件->mf_拖拽(gm->m_当前拖拽部件, C_Widget::g_鼠标, gm->m_拖放数据);
			++鼠标移动距离;
			if (事件是否传递 == E_事件是否传递::e_事件传递_终止) {
				goto To_鼠标键盘事件处理;
			}
		}
	}



	/*****************************************************************************************
	*                                 执行全局按键事件
	*****************************************************************************************/
	
	//gm->是否执行UI部件事件 = !f_执行全局按键事件(input);
	if (gm->有输入事件 && f_执行全局键盘事件(input)) {
		goto To_全局事件跳转;
	}

	if (全局鼠标事件数量) {
		auto* 全局鼠标事件 = g_全局鼠标事件.data();
		for (uint32 i = 0; i < 全局鼠标事件数量; ++i) {
			if (f_event_执行鼠标事件(&全局鼠标事件[i], input.m_Key.Keys状态, gm->鼠标按键状态)) {
				全局鼠标事件[i].event(nullptr, 全局鼠标事件[i].状态);
				goto To_全局事件跳转;
			}
		}
	}
	



	/*****************************************************************************************
	*                           上次多出部件 执行鼠标移出事件
	*****************************************************************************************/
	for (int8 i = gm->m_上一次焦点组件数量; i > 0; ) {
		--i;
		if (gm->m_上一次焦点组件[i] && gm->m_上一次焦点组件[i]->mf_鼠标离开) {
			if (i < gm->m_焦点数量) {
				if ( gm->m_上一次焦点组件[i] == gm->m_焦点组件[i]) {
					break;
				}
			}
			gm->m_上一次焦点组件[i]->mf_鼠标离开(gm->m_上一次焦点组件[i], C_Widget::g_鼠标);
		}
		gm->m_上一次焦点组件[i] = nullptr;
	}





To_鼠标键盘事件处理:

	for ( ; 当前组件迭代ID > 0 ; ) {
		--当前组件迭代ID;
		C_Widget* w = gm->m_焦点组件[当前组件迭代ID];
		

		/*****************************************************************************************
		*        上次记录部件 不同就执行上次记录鼠标移除事件 执行当前部件鼠标进入事件
		*****************************************************************************************/
		if (!gm->m_当前独占操作文本框) {
			if (事件是否传递 == E_事件是否传递::e_事件传递_继续 && w->mf_鼠标进入 && gm->m_上一次焦点组件[当前组件迭代ID] != w) {
				w->mf_鼠标进入(w, C_Widget::g_鼠标);
			}
		}
		
		gm->m_上一次焦点组件[当前组件迭代ID] = w;



		bool 不向下传递 = false;

		//鼠标左键事件
		{
			if (gm->鼠标按键状态[E_Input_鼠标按键::e_左键] == DEF_按键状态_按下) {
				
				鼠标按键事件传递 |= w->mf_鼠标按键按下(w, E_鼠标按钮::e_鼠标左键);
				


				//==================== 双击开始计时 =====================
				g时间end = clock();
				gdur = (double)(g时间end - g时间start);
				gdur = (gdur * 1000 / CLOCKS_PER_SEC);

				if (gdur > S_UI主题::ui_双击时间间隔) {
					g时间start = clock();
					g_上一轮焦点组件 = w;
					gm->执行鼠标点击 = true;
				}
				else if (g_上一轮焦点组件 == w) {
					if (w->mf_鼠标按键双击) {
						鼠标按键事件传递 |= w->mf_鼠标按键双击(w, E_鼠标按钮::e_鼠标左键);
						g双击时间 = 0;
					}
					gm->执行鼠标点击 = false;
				}


				
				if (gm->m_当前操作部件 == 0) gm->m_当前操作部件 = w;
				
				//判断最顶层组件
				if (gm->m_焦点数量 - 当前组件迭代ID == 1) {
					if (gm->m_当前独占操作文本框 && gm->m_当前独占操作文本框 != w) {
						gm->m_当前独占操作文本框->f_输入完成();
					}
					if (gm->m_当前文本输入框 && gm->m_当前文本输入框 != w && dynamic_cast<C_文本框*>(gm->m_当前文本输入框)) {
						dynamic_cast<C_文本框*>(gm->m_当前文本输入框)->f_输入完成();
					}
				}
				
				
				
				//==================== 开始拖放事件 ====================
				if (w->mf_拖拽 && gm->拖放状态 == DEF_拖放状态_准备) {
					gm->拖放状态 = DEF_拖放状态_开始拖放;
					gm->m_当前拖拽部件 = w;
					鼠标移动距离 = 0;
				}
			}


			if (gm->鼠标按键状态[E_Input_鼠标按键::e_左键] == DEF_按键状态_放开) {
				gm->鼠标左键放开传递 = w->mf_鼠标按键放开(w, E_鼠标按钮::e_鼠标左键);

				if (gm->m_当前拖拽部件 && gm->m_当前拖拽部件->mf_结束拖拽 && gm->拖放状态 == DEF_拖放状态_拖放) {
					E_事件是否传递 拖放传递 = E_事件是否传递(gm->m_当前拖拽部件->mf_结束拖拽(gm->m_当前拖拽部件, w, gm->m_拖放数据));
					//if (w->mf_结束拖拽 && w != gm->m_当前拖拽部件) {
					//	w->mf_结束拖拽(w, gm->m_当前拖拽部件, gm->m_拖放数据);
					//}
					//gm->m_当前拖拽部件->m_拖放阻止鼠标进出事件 = false;
					gm->m_当前拖拽部件 = nullptr;
					gm->拖放状态 = DEF_拖放状态_准备;
					gm->执行鼠标点击 = false;

					
					if(拖放传递 == E_事件是否传递::e_事件传递_终止) break;
				}


				if (gm->m_当前操作部件 == w) {
					auto 是否传递 = w->mf_鼠标点击(w, E_鼠标按钮::e_鼠标左键);
					if (是否传递 == E_事件是否传递::e_事件传递_继续 && 当前组件迭代ID) {
						gm->m_当前操作部件 = gm->m_焦点组件[当前组件迭代ID - 1];
						continue;
					}
					gm->m_当前操作部件 = nullptr;
				}


				鼠标移动距离 = 0;
				gm->m_当前拖拽部件 = nullptr;
				gm->拖放状态 = DEF_拖放状态_准备;
				gm->执行鼠标点击 = false;

			}
			else if (gm->鼠标按键状态[E_Input_鼠标按键::e_左键] == DEF_按键状态_放开) {
				w->mf_鼠标按键放开(w, E_鼠标按钮::e_鼠标左键);
				gm->m_当前拖拽部件 = nullptr;
				鼠标移动距离 = 0;
			}
		}

		//鼠标右键事件
		{
			if (gm->鼠标按键状态[E_Input_鼠标按键::e_右键] == DEF_按键状态_按下) {
				鼠标按键事件传递 |= w->mf_鼠标按键按下(w, E_鼠标按钮::e_鼠标右键);
			}
			else if (gm->鼠标按键状态[E_Input_鼠标按键::e_右键] == DEF_按键状态_放开) {
				鼠标按键事件传递 |= w->mf_鼠标按键放开(w, E_鼠标按钮::e_鼠标右键);
			}
		}

		//鼠标中键事件
		{
			if (gm->鼠标按键状态[E_Input_鼠标按键::e_中键] == DEF_按键状态_按下) {
				鼠标按键事件传递 |= w->mf_鼠标按键按下(w, E_鼠标按钮::e_鼠标中键);
			}
			else if (gm->鼠标按键状态[E_Input_鼠标按键::e_中键] == DEF_按键状态_放开) {
				鼠标按键事件传递 |= w->mf_鼠标按键放开(w, E_鼠标按钮::e_鼠标中键);
			}
		}

		if (f_event_执行键位绑定事件(gm->m_当前独占操作文本框 ? *gm->m_当前独占操作文本框 : *w, *gm, input, g键盘按下数量)) {
			goto To_按键状态设置;
		}

		//跳过连续类型事件
		if (鼠标按键事件传递 == E_事件是否传递::e_事件传递_终止) {
			break;
		}


		{
			//鼠标移动
			if (((S_鼠标属性*)input.m_鼠标)->lX || ((S_鼠标属性*)input.m_鼠标)->lY) {
				w->mf_鼠标移动(w, Mouse);
			}
			
			//鼠标滚轮
			if (((S_鼠标属性*)input.m_鼠标)->lZ && w->mf_鼠标滚轮) {
				w->mf_鼠标滚轮(w, C_Widget::g_鼠标);
			}
		}



		/************************************************************************/
		//                             键盘按键事件
		/************************************************************************/
		if (gm->键盘按键向下传递 == E_事件是否传递::e_事件传递_继续) {
			
			if (gm->m_当前独占操作文本框) {
				if (gm->m_当前独占操作文本框->mf_键盘按键敲击) {
					gm->键盘按键向下传递 = gm->m_当前独占操作文本框->mf_键盘按键敲击(gm->m_当前独占操作文本框, input.m_Key);
				}
			}
			else {
				if (w->mf_键盘按键敲击) gm->键盘按键向下传递 = w->mf_键盘按键敲击(w, input.m_Key);
			}
			//if(gm->键盘按键向下传递 == E_事件是否传递::e_事件传递_终止) break;
			if(gm->键盘按键向下传递 == E_事件是否传递::e_事件传递_终止) continue;
		}


		if (当前组件迭代ID > gm->m_焦点数量) break;
	}


	//==== 记录上次记录部件以执行事件 ====
	gm->m_上一次焦点组件数量 = gm->m_焦点数量 - 当前组件迭代ID;
	//std::cout<<"*********** gm->m_上一次焦点组件数量 = "<< gm->m_上一次焦点组件数量 << std::endl;

	To_按键状态设置:

	
	当前组件迭代ID = gm->m_焦点数量;
	for ( ; 当前组件迭代ID > 0 ; ) {
		--当前组件迭代ID;
		C_Widget* w = gm->m_焦点组件[当前组件迭代ID];

		if (f_event_执行拖拽事件(*w, *gm, input, g键盘按下数量)) {
			break;
		}
	}
	
	f_event_执行事件结束(*gm, input, g键盘按下数量);
	

To_全局事件跳转:
	
	{
		if (gm->鼠标按键状态[E_Input_鼠标按键::e_左键] == DEF_按键状态_放开) {
			gm->m_当前操作部件 = 0;
		}

		for (uint8 i = 0; i < 6; ++i) {
			if (gm->鼠标按键状态[i] == DEF_按键状态_按下) {
				gm->鼠标按键状态[i] = DEF_按键状态_按下中;
			}
			else if (gm->鼠标按键状态[i] == DEF_按键状态_放开) {
				gm->鼠标按键状态[i] = DEF_按键状态_准备;
			}
		}

		for (uint16 k = 0; k < 256; ++k) {
			if (input.m_Key.Keys状态[k] == DEF_按键状态_按下) {
				input.m_Key.Keys状态[k] = DEF_按键状态_按下中;
			}
			else if (input.m_Key.Keys状态[k] == DEF_按键状态_放开) {
				input.m_Key.Keys状态[k] = DEF_按键状态_准备;
			}
		}
	}

	
	C_Widget::g_鼠标.abs = C_Widget::g_鼠标.gPos;
	//std::cout << "输入事件" << std::endl;
}




static void f_更新UI动画(C_Widget* w) {
	if (w->mf_动画) {
		w->mf_动画(w);
	}

	uint32 num = w->m_子组件.size();
	if (num) {
		auto* p = w->m_子组件.data();

		for (uint32 i = 0; i < num; ++i) {
			f_更新UI动画(p[i]);
		}
	}
}


static bool f_更新UI部件布局(C_Widget* w, bool is需裁剪, C_Widget* 区域帧缓存根 = nullptr, uint32 渲染层 = 0) {
	auto* p		= w->m_子组件.data();
	uint32 num	= w->m_子组件.size();

	if (w->m_更新绘制属性) {
		if (w->mf_布局) {
			w->mf_布局(w, p, num);
			f_widget_更新绘制(w);
		}
		is需裁剪 = true;
	}

	if (is需裁剪 && w->m_父部件) {
		f_widget_裁剪组件(w->m_父部件->m_GlobalLoc, w->m_父部件->m_裁剪大小, w);
	}

	if (w->m_区域帧缓存根) {
		w->m_区域链接根 = nullptr;
		渲染层 = w->m_渲染层;
		区域帧缓存根 = w->m_区域帧缓存根;
	}
	else {
		w->m_渲染层 = 渲染层;
		w->m_区域链接根 = 区域帧缓存根;
	}

	auto sw = w->f_get更新组件();
	if (sw.m_Num && !w->m_被裁剪) {
		for (int32 i = 0; i < sw.m_Num; ++i) {
			bool 是否更新绘制组件 = f_更新UI部件布局(sw.m_W[i], is需裁剪, 区域帧缓存根, 渲染层);
		}
	}

	return is需裁剪;
}

void f_ui_更新UI布局(C_Widget管理* gm, ivec2 view) {
	
	auto e = f_widget_getTop(gm);
	for (uint8 i = 0; i < e.m_Num; ++i) {
		e.m_W[i]->m_裁剪大小 = { 0.0f,0.0f, float32(view.x), float32(view.y) };
		f_更新UI部件布局(e.m_W[i], false);
	}

	if (gm->m_Root->m_更新绘制属性) {
		gm->m_Root->m_裁剪大小 = { 0.0f,0.0f, float32(view.x), float32(view.y) };
		gm->m_Root->f_setSize(_Vec2(view));
	}
	f_更新UI部件布局(gm->m_Root, false);

}


static void f_更新UI部件属性(C_Widget* w, bool 更新深层组件 = false) {
	更新深层组件 |= w->m_更新绘制属性;

	if (更新深层组件) {
		if ( w->m_画布 && w->mf_变换) {
			f_vg_tranform(w->m_画布, w->m_GlobalLoc, w->m_GlobalScale);
			w->mf_变换(w);
		}
		w->m_更新绘制属性 = false;
		

		if (w->m_区域帧缓存根) {
			w->m_更新下层绘制 = true;
		}
		else {
			w->m_更新下层绘制 = false;
		}
	}

	uint32 num = w->m_子组件.size();
	if (num && !w->m_被裁剪) {
		auto* p = w->m_子组件.data();
		for (int32 i = 0; i < num; ++i) {
			f_更新UI部件属性(p[i], 更新深层组件);
		}
	}
}

void f_ui_更新UI部件属性(C_Widget管理* gm, ivec2 view) {
	gm->f_裁剪层();

	auto e = f_widget_getTop(gm);
	for (uint8 i = 0; i < e.m_Num; ++i) {
		f_更新UI部件属性(e.m_W[i]);
	}
	f_更新UI部件属性(gm->m_Root);
	
	gm->m_UICtx->f_准备图层渲染();

	gm->mf_输入执行后回调();
}




void f_ui_绘制组件(C_Widget管理* gm) {
	
	auto e = f_widget_getTop(gm);
	for (uint8 i = 0; i < e.m_Num; ++i) {
		e.m_W[i]->f_绘图();
	}

	gm->m_Root->f_绘图();
}

//auto 组件层级大小比较 = [](const C_Widget* a, const C_Widget* b) -> bool {
//	return a->m_层级ID < b->m_层级ID;
//};

bool f_ui_渲染图层(C_Widget管理* gm, ivec2 view) {
	
	static vec2 viewOffset[32] = {
		{0,0},

		{0,1},
		{1,0},
		{0,-1},
		{-1,0},

		{0.707107,	0.707107},
		{0.707107,	-0.707107},
		{-0.707107,	-0.707107},
		{-0.707107,	0.707107},

		{0,2},
		{1,1.7321},
		{1.7321,1},
		{2,0},

		{1.7321,-1},
		{1,-1.7321},
		{0,-2},
		{-1,-1.7321},

		{-1.7321,-1},
		{-2,0},
		{-1.7321,1},
		{-1,1.7321},
	};
	static float32 viewSizeOffset[32] = {
		0,
		0.2,
		0.2,
		0.2,
		0.2,
		0.2,
		0.2,
		0.2,
		0.2,

		0.35,
		0.35,
		0.35,
		0.35,
		0.35,
		0.35,
		0.35,
		0.35,
		0.35,
		0.35,
		0.35,
		0.35,
	};


	gm->裁剪 = { {0,0}, {uint32(view.x), uint32(view.y)} };
	//gm->m_渲染参数.m_视口 = &gm->视口;
	//gm->m_渲染参数.m_裁剪 = &gm->裁剪;
	
	
	gm->m_UICtx->f_update_纹理绑定();
	
	bool 累计记录 = false;
	bool 模糊纹理 = false;
	uint32 层 = 0;
	
	
	//std::cout<< "渲染层 ====================== " << gm->m_帧渲染层.size() << " ===================== " << "\n";
	S_Rect2D 裁剪{{}, {view.x, view.y}};

	

	for (auto& e : gm->m_帧渲染层) {
		bool 下层更新 = false;
		uint32 采样层区域偏移 = gm->m_UICtx->m_层区域采样属性.size();
		//std::cout<< " ========层======= " << 层 << " ======下层更新====== " << 下层更新 << "\n";
		vec4 最大裁剪区域{1000000, 10000000, -1000000, -1000000};
		
		if (e->m_顶层) {
			最大裁剪区域 = { 0, 0, float32(view.x), float32(view.y) };
			for (auto& area : e->m_渲染区域) {
				if (area.first->m_更新下层绘制) {
					下层更新 = true;
				}

				S_FrameSample_TAA fs;
				f_widget_UI层区域属性(fs, 最大裁剪区域, true, 0);
				gm->m_UICtx->m_层区域采样属性.push_back(fs);
			}
			下层更新 = true;
			e->m_帧累计 = 0;

		}
		else {
			uint8 debugNum = 0;
			for (auto& area : e->m_渲染区域) {
				auto w = area.first;
				if (w->m_更新下层绘制) {
					++debugNum;
				}
			}

			for (auto& area : e->m_渲染区域) {
				auto w = area.first;
				if (w->m_更新下层绘制) {
					最大裁剪区域 = f_widget_区域合并(最大裁剪区域, w);
					下层更新 = true;
				}

				S_FrameSample_TAA fs;
				f_widget_UI层区域属性(fs, w->m_裁剪大小, w->m_更新下层绘制, debugNum);
				gm->m_UICtx->m_层区域采样属性.push_back(fs);
			}
			//最大裁剪区域 = { 0, 0, float32(view.x), float32(view.y) };
		}
		

		if (下层更新) {
			裁剪 = f_widget_裁剪转区域(最大裁剪区域);
			
			if (e->m_帧累计 <= 1) {
				模糊纹理 = true;
			}

			if (e->m_帧累计 < DEF_UI_Sample_Num) {
				f_vg_begin(*gm->m_UICtx, gm, viewOffset[e->m_帧累计] * viewSizeOffset[e->m_帧累计] * 0.95);
				f_Draw_Begin_帧缓存(gm->m_UICtx->m_Ctx, e->m_sruface->m_帧缓存, 0, 裁剪);
				f_vg_set2DView(gm->m_UICtx->m_Ctx, {{}, _Vec2(view)}, nullptr);

				for (auto& area : e->m_渲染区域) {
					auto w = area.first;
					
					auto& 渲染组件 = area.second;
					if (e->m_顶层) {
						渲染组件.m_渲染组件 = {area.first};
					}
					else {
						if (!w->m_更新下层绘制) {
							continue;
						}

						if (area.second.m_重排序) {
							渲染组件.m_渲染组件.clear();

							f_绘制子组件收集(w, w, 渲染组件, 层);
							area.second.m_重排序 = false;
						}
					}
					

					for (auto& we : area.second.m_渲染组件) {
						gm->f_绘制子组件(we);
					}
				}

				f_Draw_end_帧缓存(gm->m_UICtx->m_Ctx);
				累计记录 = true;
			}
			else {
				e->m_帧累计 = DEF_UI_Sample_Num + 1;

				for (auto& area : e->m_渲染区域) {
					auto w = area.first;
					w->m_更新下层绘制 = false;
				}
			}


			++e->m_帧累计;

			gm->m_帧采样属性[层].m_LayerArea_Offset = f_widget_UI层区域(_uVec2(最大裁剪区域.x, 最大裁剪区域.y));
			gm->m_帧采样属性[层].m_LayerArea_Size = f_widget_UI层区域(_uVec2(最大裁剪区域.z, 最大裁剪区域.w));
		}

		gm->m_帧采样属性[层].m_LayerAttr = f_widget_UI层采样属性(e->m_帧累计, 采样层区域偏移, e->m_渲染区域.size());
		++层;
	}

	
	if (累计记录) {
		f_buf_fill(gm->m_采样属性, 0, gm->m_帧采样属性, 层 * sizeof(S_FrameSample_TAA));
		f_buf_fill(gm->m_UICtx->m_层区域属性, 0, gm->m_UICtx->m_层区域采样属性.data(), (gm->m_UICtx->m_层区域采样属性.size() + 1) * sizeof(S_FrameSample_TAA));
		f_vg_Accumulate(gm, _uVec2(view), 层);
	}
	

	if (模糊纹理) {
		f_vg_Blur(gm, _uVec2(view), 层);
	}

	return 累计记录;
}

void f_ui_合成到屏幕(C_Widget管理* gm, ivec2 view) {
	S_Rect2Df rect{{}, _Vec2(view)};

	f_vg_set2DView(gm->m_UICtx->m_Ctx, rect, nullptr);
	f_vg_tranform(gm->m_UICtx->m_合成画布, {0,0});

	std::vector<mat2> vert;
	uint32 层 = 0;
	for (auto& e : gm->m_UICtx->m_合成画布->m_绘制元素) {
		//gm->m_UICtx->m_DS_合成->f_bind(e->m_常量推送);

		f_vg_setComposition(gm->m_UICtx->m_Ctx, *e, 层, 1, rect);
		f_vg_render2((gm->m_UICtx->m_Ctx), *e, E_管线槽::e_UI合成);

		++层;
	}
	//f_vg_drawComposition(gm->m_UICtx->m_Ctx, *m_ui合成, m_窗口GM->m_帧渲染层.size(), {{0,0}, {m_Size.x, m_Size.y}});
}


void f_ui_push纹理填充(S_纹理* tex, uint8* data, uvec3 dim) {
	if (g_纹理填充列队.size() == 0) {
		g_纹理填充列队.push_back({ dim, tex, data });
	}
}

void f_ui_run纹理填充() {

}


uint16 f_ui_管理器添加根部件(C_Widget管理* gm, C_Widget* w) {
	gm->m_根部件切换组.push_back(w);
	w->m_实例ID = gm->m_根部件切换组.size() - 1;
	w->f_绑定窗口管理(gm);
	return w->m_实例ID;
}

void f_ui_switchRootWidget(C_Widget管理* gm, uint16 id) {
	if (gm->m_Root->mf_打开关闭) gm->m_Root->mf_打开关闭(gm->m_Root, false);
	gm->m_Root = gm->m_根部件切换组[id];
	gm->m_Root->m_更新绘制属性 = true;

	if (gm->m_Root->mf_打开关闭) gm->m_Root->mf_打开关闭(gm->m_Root, true);
}

vec2 f_ui_get空间投影比例(const S_Rect2Df& rect, Mat44f& 投影矩阵, float32 视点距离) {
	Mat44f mat = f_mat44_identity();
	mat.m32 = 视点距离;

	vec2 coord1 = f_Project空间坐标转屏幕(投影矩阵, mat, { 0, 0, 0 }, rect);
	vec2 coord2 = f_Project空间坐标转屏幕(投影矩阵, mat, { 1, 1, 0 }, rect);

	return coord2 - coord1;
}

vec2 f_ui_get空间投影比例(const S_Rect2Df& rect, const S_摄像机& camera) {

	vec3 视线 = f_camera_get视线向量(camera);
	vec3 相机位置 = f_camera_get眼睛位置(camera);

	vec4 p = f_graph_坐标构建平面(相机位置, 视线);

	float32 d = fabs(f_graph_点到平面距离(相机位置, p));

	auto mat = f_mat44_identity();
	mat.m32 = camera.m_视距;

	vec2 coord1 = f_Project空间坐标转屏幕(camera.m_相机投影矩阵, mat, { 0, 0, 0 }, rect);
	vec2 coord2 = f_Project空间坐标转屏幕(camera.m_相机投影矩阵, mat, { 1, 1, 0 }, rect);
	return coord2 - coord1;
}

vec2 f_ui_get空间投影比例(const S_Rect2Df& rect, const S_摄像机& camera, vec2 s, vec2 e) {
	vec3 视线 = f_camera_get视线向量(camera);
	vec4 p = f_graph_坐标构建平面(camera.m_视点, 视线);

	vec3 相机位置 = f_camera_get眼睛位置(camera);
	float32 d = fabs(f_graph_点到平面距离(-相机位置, p));

	auto mat = f_mat44_identity();
	mat.m32 = d;

	vec2 coord1 = f_Project空间坐标转屏幕(camera.m_相机投影矩阵, mat, { s.x, s.y, 0 }, rect);
	vec2 coord2 = f_Project空间坐标转屏幕(camera.m_相机投影矩阵, mat, { e.x, e.y, 0 }, rect);
	return coord2 - coord1;
}

void f_ui_注册全局快捷键(std::vector<uint8>& Key, fp_Widget全局按键按下 func) {
	uint64 k = 0;
	uint8 num = Key.size();
	for (uint8 i = 0; i < num; ++i) {
		k |= (Key[i] << (i * 8));
	}

	k |= (uint64(num) << (7 * 8));

	g_全局按键事件[k] = func;
}

void f_ui_注册全局快捷键(const S_键盘键位映射& Key) {
	g_全局键盘事件.push_back(Key);

	std::sort(g_全局键盘事件.begin(), g_全局键盘事件.end(), [](const S_键盘键位映射& keyA, const S_键盘键位映射& keyB) {
		uint32 a = keyA.键盘按键[0] | keyA.键盘按键[1]<<8 | keyA.键盘按键[2] << 16 | keyA.键盘按键[3] << 24;
		uint32 b = keyB.键盘按键[0] | keyB.键盘按键[1]<<8 | keyB.键盘按键[2] << 16 | keyB.键盘按键[3] << 24;
		
		return ( a > b );
	});
}

void f_ui_注册全局鼠标快捷键(const S_鼠标键位映射& Key) {
	g_全局鼠标事件.push_back(Key);
}

void f_ui_注册键盘快捷键(C_Widget* self, E_键位操作类型 操作类型, fp_Widget快捷键事件 event, uint8 any, bool ctrl, bool shift, bool alt) {
	S_键盘键位映射* km = (S_键盘键位映射*)malloc(sizeof(S_键盘键位映射));
	(*km) = {};
	km->event = event;
	km->键盘按键[3] = any;

	switch (操作类型) {
	case E_键位操作类型::e_键位_按下: 
		km->键盘状态[3] = DEF_按键状态_按下;
		break;
	case E_键位操作类型::e_键位_放开:
		km->键盘状态[3] = DEF_按键状态_放开;
		break;
	default:
		break;
	}
	assert(km);
	self->m_键位映射.push_back((S_键位映射*)km);
}

void f_ui_注册鼠标快捷键(C_Widget* self, E_键位操作类型 操作类型, fp_Widget快捷键事件 event, E_Input_鼠标按键 any, bool ctrl, bool shift, bool alt) {
	S_鼠标键位映射* km = (S_鼠标键位映射*)malloc(sizeof(S_鼠标键位映射));
	(*km) = {};
	km->event = event;
	(*km->键盘按键) = {};
	(*km->键盘状态) = {};
	assert(km);
	self->m_键位映射.push_back((S_键位映射*)km);
}

void f_ui_注册键盘快捷键(C_Widget* self, S_键盘键位映射* km) {
	self->m_键位映射.push_back((S_键位映射*)km);
}

void f_ui_注册鼠标快捷键(C_Widget* self, S_键位映射* km) {
	for (auto& e : self->m_键位映射) {
		if (e == km) {
			return;
		}
	}
	assert(km);
	self->m_键位映射.push_back((S_键位映射*)km);
}

void f_ui_整理快捷键(C_Widget* self) {
	
	std::sort(self->m_键位映射.begin(), self->m_键位映射.end(), [](const S_键位映射* km_a, const S_键位映射* km_b){
		
		auto 计算键位大小 = [](const S_键位映射* km_c) {
			uint32 mask = 0;
			switch (km_c->m_Type) {
				case E_键位映射类型::e_键映射类型_拖拽: {
					S_拖拽键位映射* km = (S_拖拽键位映射*)km_c;

					for (uint8 k = 0; k < 4; ++k) {
						mask |= km->键盘按键[k] ? 1 << k : 0;
					}
					for (uint8 k = 0; k < 4; ++k) {
						mask += km->鼠标状态[k] ? 1 << (k + 4) : 0;
					}
					break;
				}
				case E_键位映射类型::e_键映射类型_键盘: {
					S_键盘键位映射* km = (S_键盘键位映射*)km_c;

					for (uint8 k = 0; k < 4; ++k) {
						mask |= km->键盘按键[k] ? 1 << k : 0;
					}
					break;
				}
				case E_键位映射类型::e_键映射类型_鼠标: {
					S_鼠标键位映射* km = (S_鼠标键位映射*)km_c;

					for (uint8 k = 0; k < 4; ++k) {
						mask |= km->键盘按键[k] ? 1 << k : 0;
					}
					for (uint8 k = 0; k < 4; ++k) {
						mask += km->鼠标状态[k] ? 1 << (k + 4) : 0;
					}
					break;
				}
				case E_键位映射类型::e_键映射类型_双击: {
					S_鼠标双击键位映射* km = (S_鼠标双击键位映射*)km_c;

					for (uint8 k = 0; k < 4; ++k) {
						mask |= km->键盘按键[k] ? 1 << k : 0;
					}
					for (uint8 k = 0; k < 4; ++k) {
						mask += km->鼠标状态[k] ? 1 << (k + 4) : 0;
					}
					break;
				}
			}
			return mask;
		};

		auto maskA = 计算键位大小(km_a);
		auto maskB = 计算键位大小(km_b);

		return (maskA > maskB);

	});
}





void f_ui添加图标组(C_Widget管理* gm, std::vector<S_纹理组添加参数> 添加参数) {
	for (auto& e : 添加参数) {
		gm->f_加载图标(e.m_GroupName, e.m_Path);
	}
}

void f_ui加载字体(S_UI渲染环境* ctx, const std::vector<S_字体加载参数>& 添加参数){
	for (auto& e : 添加参数) {
		f_surface_加载字体(*ctx, e);
	}
}

void f_ui_释放图标组(C_Widget管理* gm) {
	for (auto& e : gm->m_UICtx->m_Mat->m_ICOs) {
		f_tex_销毁纹理(e.second.m_Tex);
	}
}

void f_ui_释放字体(C_Widget管理* gm) {
	for (auto& e : gm->m_UICtx->m_Mat->m_Fonts) {
		f_tex_销毁纹理(e.second.m_Tex);
	}
}



void f_ui_文件拖入(C_Widget管理* gm, const vec2& point) {
	f_ui_筛选焦点组件(gm, point);

	if (gm->m_焦点数量) {
		C_Widget* w = gm->m_焦点组件[gm->m_焦点数量 - 1];

		if (w->mf_文件处理回调 && C_Widget管理::m_拖放文件名.size()) {
			w->mf_文件处理回调(w, C_Widget管理::m_拖放文件名, E_对话框类型::e_关闭);
		}
	}
	C_Widget管理::m_拖放文件名.clear();
}

void f_ui_更新绑定数据(C_Widget管理* gm) {
	f_widget_执行待添加部件();
	f_widget_动态销毁UI部件(gm);

	f_ui_树形框_更新数据添加();

	f_菜单_构建动态菜单();
}





/*******************************************************************/
//                         Vulkan 缓存数据处理
/*******************************************************************/
//if (g_纹理填充列队.size()) {
//	for (auto& e : g_纹理填充列队) {
//		f_tex_修改大小(e.m_Tex, e.m_Dim, false);
//		f_tex_填充纹理数据(e.m_Tex, e.m_Data, sizeof(S_RGBA8UI), e.m_Dim);
//	}
//	g_纹理填充列队.clear();
//}



